package com.smart.community.region.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.commons.cache.DataScopeInfo;
import com.smart.community.commons.enums.SystemStatusEnum;
import com.smart.community.commons.exception.BusinessException;
import com.smart.community.commons.result.PageResult;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.region.service.DataScopeService;
import com.smart.community.region.dto.OwnerHouseholdDTO;
import com.smart.community.region.dto.OwnerHouseholdQueryDTO;
import com.smart.community.region.entity.OwnerHousehold;
import com.smart.community.region.entity.Owner;
import com.smart.community.region.mapper.OwnerMapper;
import com.smart.community.region.entity.Household;
import com.smart.community.region.entity.Unit;
import com.smart.community.region.entity.Building;
import com.smart.community.region.entity.Community;
import com.smart.community.region.mapper.OwnerHouseholdMapper;
import com.smart.community.region.service.IBuildingService;
import com.smart.community.region.service.ICommunityService;
import com.smart.community.region.service.IHouseholdService;
import com.smart.community.region.service.IOwnerHouseholdService;

import com.smart.community.region.service.IUnitService;
import com.smart.community.region.vo.OwnerHouseholdVO;

import lombok.extern.slf4j.Slf4j;

/**
 * 业主房户关联服务实现类
 * 
 * 功能说明：
 * 1. 提供业主房户关联的CRUD操作
 * 2. 支持数据权限过滤
 * 3. 合理的查询优化和Redis缓存策略
 * 4. 通过TypeSafeRedisSerializer支持复杂对象缓存，提升系统性能
 * 5. 遵循权威文档规范，支持缓存复杂对象（OwnerHousehold实体、OwnerHouseholdVO等）
 * 
 * @author Wu.Liang
 * @since 2025-08-20
 * @version 1.2.0 - 恢复复杂对象缓存，遵循权威文档规范
 */
@Slf4j
@Service
public class OwnerHouseholdServiceImpl extends ServiceImpl<OwnerHouseholdMapper, OwnerHousehold> implements IOwnerHouseholdService {
    
    @Autowired
    private DataScopeService dataScopeService;
    
    @Autowired
    private ICommunityService communityService;
    
    @Autowired
    private IBuildingService buildingService;
    
    @Autowired
    private IUnitService unitService;
    
    @Autowired
    private IHouseholdService householdService;
    
    @Autowired
    private OwnerMapper ownerMapper;
    
    @Autowired
    private org.springframework.cache.CacheManager cacheManager;
    
    @Override
    @Cacheable(value = "owner_household:owner", key = "#ownerId", unless = "#result == null || #result.isEmpty()")
    public List<OwnerHousehold> getByOwnerId(Long ownerId) {
        long startTime = System.currentTimeMillis();
        log.info("根据业主ID查询关联的房户列表，业主ID：{}", ownerId);
        
        try {
            if (ownerId == null) {
                log.warn("业主ID为空，返回空列表");
                return Collections.emptyList();
            }
            
            List<OwnerHousehold> result = baseMapper.selectByOwnerId(ownerId);
            long endTime = System.currentTimeMillis();
            log.info("根据业主ID查询关联的房户列表成功，耗时：{}ms，业主ID：{}，记录数：{}", endTime - startTime, ownerId, result.size());
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("根据业主ID查询关联的房户列表失败，耗时：{}ms，业主ID：{}", endTime - startTime, ownerId, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @Cacheable(value = "owner_household:vos", key = "#ownerId", unless = "#result == null || #result.isEmpty()")
    public List<OwnerHouseholdVO> getOwnerHouseholdVOs(Long ownerId) {
        long startTime = System.currentTimeMillis();
        log.info("根据业主ID查询关联的房户列表（VO格式），业主ID：{}", ownerId);
        
        try {
            if (ownerId == null) {
                log.warn("业主ID为空，返回空列表");
                return Collections.emptyList();
            }
            
            // 获取当前用户ID
            Long currentUserId = SecurityUtils.getCurrentUserId();
            if (currentUserId == null) {
                log.warn("当前用户未登录，返回空列表");
                return Collections.emptyList();
            }
            
            // 应用数据权限过滤
            List<OwnerHousehold> ownerHouseholds = getOwnerHouseholdsWithDataPermission(ownerId, currentUserId);
            List<OwnerHouseholdVO> result = convertToVOList(ownerHouseholds);
            
            long endTime = System.currentTimeMillis();
            log.info("根据业主ID查询关联的房户列表（VO格式）成功，耗时：{}ms，业主ID：{}，记录数：{}", endTime - startTime, ownerId, result.size());
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("根据业主ID查询关联的房户列表（VO格式）失败，耗时：{}ms，业主ID：{}", endTime - startTime, ownerId, e);
            return Collections.emptyList();
        }
    }
    
    /**
     * 应用数据权限过滤获取业主房户关联列表
     * 
     * @param ownerId 业主ID
     * @param currentUserId 当前用户ID
     * @return 过滤后的业主房户关联列表
     */
    private List<OwnerHousehold> getOwnerHouseholdsWithDataPermission(Long ownerId, Long currentUserId) {
        log.info("应用数据权限过滤获取业主房户关联列表，业主ID：{}，当前用户ID：{}", ownerId, currentUserId);
        
        try {
            // 第1步：检查用户是否为超级管理员
            boolean isSuperAdmin = checkIsSuperAdmin(currentUserId);
            if (isSuperAdmin) {
                log.info("超级管理员用户，返回所有数据，业主ID：{}", ownerId);
                return baseMapper.selectByOwnerId(ownerId);
            }
            
            // 第2步：检查用户是否有关联物业公司
            boolean hasPropertyCompany = checkUserHasPropertyCompany(currentUserId);
            if (!hasPropertyCompany) {
                log.warn("用户未关联物业公司，返回空列表，用户ID：{}", currentUserId);
                return Collections.emptyList();
            }
            
            // 第3步：获取用户可访问的房户ID集合
            List<Long> accessibleHouseholdIds = getUserAccessibleHouseholdIds(currentUserId);
            if (accessibleHouseholdIds.isEmpty()) {
                log.warn("用户无权限访问任何房户，返回空列表，用户ID：{}", currentUserId);
                return Collections.emptyList();
            }
            
            // 第4步：获取业主关联的所有房户
            List<OwnerHousehold> allOwnerHouseholds = baseMapper.selectByOwnerId(ownerId);
            if (allOwnerHouseholds.isEmpty()) {
                log.info("业主未关联任何房户，业主ID：{}", ownerId);
                return Collections.emptyList();
            }
            
            // 第5步：过滤出用户有权限访问的房户关联
            List<OwnerHousehold> filteredOwnerHouseholds = allOwnerHouseholds.stream()
                .filter(ownerHousehold -> accessibleHouseholdIds.contains(ownerHousehold.getHouseholdId()))
                .collect(Collectors.toList());
            
            log.info("数据权限过滤完成，业主ID：{}，原始关联数量：{}，过滤后关联数量：{}", 
                    ownerId, allOwnerHouseholds.size(), filteredOwnerHouseholds.size());
            
            return filteredOwnerHouseholds;
            
        } catch (Exception e) {
            log.error("应用数据权限过滤失败，业主ID：{}，用户ID：{}", ownerId, currentUserId, e);
            // 异常时返回空列表，确保数据安全
            return Collections.emptyList();
        }
    }
    
    /**
     * 检查用户是否为超级管理员
     * 
     * @param userId 用户ID
     * @return 是否为超级管理员
     */
    private boolean checkIsSuperAdmin(Long userId) {
        try {
            // 通过DataScopeService检查用户是否为超级管理员
            DataScopeInfo dataScopeInfo = dataScopeService.getUserDataScope(userId);
            return dataScopeInfo != null && dataScopeInfo.isSuperAdmin();
        } catch (Exception e) {
            log.error("检查用户是否为超级管理员失败，用户ID：{}", userId, e);
            return false;
        }
    }
    
    /**
     * 检查用户是否有关联物业公司
     * 
     * @param userId 用户ID
     * @return 是否有关联物业公司
     */
    private boolean checkUserHasPropertyCompany(Long userId) {
        try {
            // 通过DataScopeService检查用户是否有关联物业公司
            DataScopeInfo dataScopeInfo = dataScopeService.getUserDataScope(userId);
            return dataScopeInfo != null && dataScopeInfo.isPropertyCompanyUser();
        } catch (Exception e) {
            log.error("检查用户是否有关联物业公司失败，用户ID：{}", userId, e);
            return false;
        }
    }
    
    /**
     * 获取用户可访问的房户ID集合
     * 按照数据权限层级：物业公司 → 社区 → 楼栋 → 单元 → 房户
     * 
     * @param userId 用户ID
     * @return 可访问的房户ID集合
     */
    private List<Long> getUserAccessibleHouseholdIds(Long userId) {
        log.info("获取用户可访问的房户ID集合，用户ID：{}", userId);
        
        try {
            // 第1步：获取用户关联的物业公司ID
            DataScopeInfo dataScopeInfo = dataScopeService.getUserDataScope(userId);
            if (dataScopeInfo == null || !dataScopeInfo.isPropertyCompanyUser()) {
                log.warn("用户未关联物业公司，用户ID：{}", userId);
                return Collections.emptyList();
            }
            
            List<Long> propertyCompanyIds = dataScopeInfo.getPropertyCompanyIds();
            if (propertyCompanyIds == null || propertyCompanyIds.isEmpty()) {
                log.warn("用户物业公司ID为空，用户ID：{}", userId);
                return Collections.emptyList();
            }
            
            // 第2步：获取物业公司关联的社区ID集合
            List<Long> communityIds = dataScopeInfo.getCommunityIds();
            if (communityIds == null || communityIds.isEmpty()) {
                log.warn("物业公司未关联任何社区，物业公司IDs：{}", propertyCompanyIds);
                return Collections.emptyList();
            }
            
            // 第3步：根据社区ID集合获取楼栋ID集合
            List<Long> buildingIds = buildingService.getBuildingIdsByCommunityIds(communityIds);
            if (buildingIds.isEmpty()) {
                log.warn("社区下无楼栋数据，社区IDs：{}", communityIds);
                return Collections.emptyList();
            }
            
            // 第4步：根据楼栋ID集合获取单元ID集合
            List<Long> unitIds = unitService.getUnitIdsByBuildingIds(buildingIds);
            if (unitIds.isEmpty()) {
                log.warn("楼栋下无单元数据，楼栋IDs：{}", buildingIds);
                return Collections.emptyList();
            }
            
            // 第5步：根据单元ID集合获取房户ID集合
            List<Long> householdIds = householdService.getHouseholdIdsByUnitIds(unitIds);
            
            log.info("获取用户可访问的房户ID集合完成，用户ID：{}，物业公司IDs：{}，社区数量：{}，楼栋数量：{}，单元数量：{}，房户数量：{}", 
                    userId, propertyCompanyIds, communityIds.size(), buildingIds.size(), unitIds.size(), householdIds.size());
            
            return householdIds;
            
        } catch (Exception e) {
            log.error("获取用户可访问的房户ID集合失败，用户ID：{}", userId, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @Cacheable(value = "owner_household:household", key = "#householdId", unless = "#result == null || #result.isEmpty()")
    public List<OwnerHousehold> getByHouseholdId(Long householdId) {
        long startTime = System.currentTimeMillis();
        log.info("根据房户ID查询关联的业主列表，房户ID：{}", householdId);
        
        try {
            if (householdId == null) {
                log.warn("房户ID为空，返回空列表");
                return Collections.emptyList();
            }
            
            List<OwnerHousehold> result = baseMapper.selectByHouseholdId(householdId);
            long endTime = System.currentTimeMillis();
            log.info("根据房户ID查询关联的业主列表成功，耗时：{}ms，房户ID：{}，记录数：{}", endTime - startTime, householdId, result.size());
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("根据房户ID查询关联的业主列表失败，耗时：{}ms，房户ID：{}", endTime - startTime, householdId, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @Cacheable(value = "owner_household:household_vos", key = "#householdId", unless = "#result == null || #result.isEmpty()")
    public List<OwnerHouseholdVO> getHouseholdOwnerVOs(Long householdId) {
        long startTime = System.currentTimeMillis();
        log.info("根据房户ID查询关联的业主列表（VO格式），房户ID：{}", householdId);
        
        try {
            if (householdId == null) {
                log.warn("房户ID为空，返回空列表");
                return Collections.emptyList();
            }
            
            List<OwnerHousehold> ownerHouseholds = baseMapper.selectByHouseholdId(householdId);
            List<OwnerHouseholdVO> result = convertToVOList(ownerHouseholds);
            
            long endTime = System.currentTimeMillis();
            log.info("根据房户ID查询关联的业主列表（VO格式）成功，耗时：{}ms，房户ID：{}，记录数：{}", endTime - startTime, householdId, result.size());
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("根据房户ID查询关联的业主列表（VO格式）失败，耗时：{}ms，房户ID：{}", endTime - startTime, householdId, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @Cacheable(value = "owner_household:household_ids", key = "#householdIds.toString()", unless = "#result == null || #result.isEmpty()")
    public List<OwnerHousehold> getByHouseholdIds(List<Long> householdIds) {
        long startTime = System.currentTimeMillis();
        log.info("根据房户ID集合查询关联的业主列表，房户数量：{}", householdIds != null ? householdIds.size() : 0);
        
        try {
            if (householdIds == null || householdIds.isEmpty()) {
                log.warn("房户ID集合为空，返回空列表");
                return Collections.emptyList();
            }
            
            LambdaQueryWrapper<OwnerHousehold> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(OwnerHousehold::getHouseholdId, householdIds);
            queryWrapper.eq(OwnerHousehold::getStatus, SystemStatusEnum.ENABLED.getCode());
            queryWrapper.orderByDesc(OwnerHousehold::getCreateTime);
            
            List<OwnerHousehold> ownerHouseholds = this.list(queryWrapper);
            
            long endTime = System.currentTimeMillis();
            log.info("根据房户ID集合查询关联的业主列表成功，耗时：{}ms，房户数量：{}，关联记录数量：{}", endTime - startTime, householdIds.size(), ownerHouseholds.size());
            return ownerHouseholds;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("根据房户ID集合查询关联的业主列表失败，耗时：{}ms，房户IDs：{}", endTime - startTime, householdIds, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @Cacheable(value = "owner_household:owner_household", key = "#ownerId + '_' + #householdId", unless = "#result == null")
    public OwnerHousehold getByOwnerIdAndHouseholdId(Long ownerId, Long householdId) {
        long startTime = System.currentTimeMillis();
        log.info("根据业主ID和房户ID查询关联记录，业主ID：{}，房户ID：{}", ownerId, householdId);
        
        try {
            if (ownerId == null || householdId == null) {
                log.warn("业主ID或房户ID为空，返回null");
                return null;
            }
            
            OwnerHousehold result = baseMapper.selectByOwnerIdAndHouseholdId(ownerId, householdId);
            long endTime = System.currentTimeMillis();
            log.info("根据业主ID和房户ID查询关联记录成功，耗时：{}ms，业主ID：{}，房户ID：{}", endTime - startTime, ownerId, householdId);
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("根据业主ID和房户ID查询关联记录失败，耗时：{}ms，业主ID：{}，房户ID：{}", endTime - startTime, ownerId, householdId, e);
            return null;
        }
    }
    
    @Override
    @Cacheable(value = "owner_household:primary", key = "#householdId", unless = "#result == null")
    public OwnerHousehold getPrimaryOwnerByHouseholdId(Long householdId) {
        long startTime = System.currentTimeMillis();
        log.info("根据房户ID查询主业主，房户ID：{}", householdId);
        
        try {
            if (householdId == null) {
                log.warn("房户ID为空，返回null");
                return null;
            }
            
            OwnerHousehold result = baseMapper.selectPrimaryOwnerByHouseholdId(householdId);
            long endTime = System.currentTimeMillis();
            log.info("根据房户ID查询主业主成功，耗时：{}ms，房户ID：{}", endTime - startTime, householdId);
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("根据房户ID查询主业主失败，耗时：{}ms，房户ID：{}", endTime - startTime, householdId, e);
            return null;
        }
    }
    
    @Override
    @Cacheable(value = "owner_household:primary_households", key = "#ownerId", unless = "#result == null || #result.isEmpty()")
    public List<OwnerHousehold> getPrimaryHouseholdsByOwnerId(Long ownerId) {
        long startTime = System.currentTimeMillis();
        log.info("根据业主ID查询主业主的房户列表，业主ID：{}", ownerId);
        
        try {
            if (ownerId == null) {
                log.warn("业主ID为空，返回空列表");
                return Collections.emptyList();
            }
            
            List<OwnerHousehold> result = baseMapper.selectPrimaryHouseholdsByOwnerId(ownerId);
            long endTime = System.currentTimeMillis();
            log.info("根据业主ID查询主业主的房户列表成功，耗时：{}ms，业主ID：{}，记录数：{}", endTime - startTime, ownerId, result.size());
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("根据业主ID查询主业主的房户列表失败，耗时：{}ms，业主ID：{}", endTime - startTime, ownerId, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @CacheEvict(value = {
        "owner_household:owner", "owner_household:household", "owner_household:vos", 
        "owner_household:household_vos", "owner_household:household_ids", "owner_household:owner_household", 
        "owner_household:primary", "owner_household:primary_households", "owner_household:exists", "owner_household:vo"
    }, allEntries = true)
    public void createOwnerHousehold(Long ownerId, Long householdId, Boolean isPrimaryOwner) {
        log.info("创建业主房户关联，业主ID：{}，房户ID：{}，是否主业主：{}", ownerId, householdId, isPrimaryOwner);
        
        if (ownerId == null || householdId == null) {
            throw new BusinessException("业主ID和房户ID不能为空");
        }
        
        // 检查关联是否已存在
        if (existsByOwnerIdAndHouseholdId(ownerId, householdId)) {
            throw new BusinessException("业主房户关联已存在");
        }
        
        // 构建关联对象
        OwnerHousehold ownerHousehold = new OwnerHousehold();
        ownerHousehold.setOwnerId(ownerId);
        ownerHousehold.setHouseholdId(householdId);
        ownerHousehold.setOwnershipType(1); // 默认完全产权
        ownerHousehold.setOwnershipRatio(BigDecimal.valueOf(100.00)); // 默认100%产权
        ownerHousehold.setIsPrimaryOwner(isPrimaryOwner != null && isPrimaryOwner ? 1 : 0);
        ownerHousehold.setStatus(SystemStatusEnum.ENABLED.getCode());
        
        // 设置创建人和更新人
        Long currentUserId = SecurityUtils.getCurrentUserId();
        ownerHousehold.setCreateBy(currentUserId);
        ownerHousehold.setUpdateBy(currentUserId);
        LocalDateTime now = LocalDateTime.now();
        ownerHousehold.setCreateTime(now);
        ownerHousehold.setUpdateTime(now);
        
        // 保存关联信息
        this.save(ownerHousehold);
        
        log.info("创建业主房户关联成功，关联ID：{}", ownerHousehold.getId());
    }
    
    @Override
    @CacheEvict(value = {
        "owner_household:owner", "owner_household:household", "owner_household:vos", 
        "owner_household:household_vos", "owner_household:household_ids", "owner_household:owner_household", 
        "owner_household:primary", "owner_household:primary_households", "owner_household:exists", "owner_household:vo"
    }, allEntries = true)
    public Long createOwnerHousehold(OwnerHouseholdDTO dto) {
        log.info("创建业主房户关联（DTO方式），业主ID：{}，房户ID：{}", dto.getOwnerId(), dto.getHouseholdId());
        if (dto.getOwnerId() == null || dto.getHouseholdId() == null) {
            throw new BusinessException("业主ID和房户ID不能为空");
        }
        
        // 检查关联是否已存在
        if (existsByOwnerIdAndHouseholdId(dto.getOwnerId(), dto.getHouseholdId())) {
            throw new BusinessException("业主房户关联已存在");
        }
        
        // 构建关联对象
        OwnerHousehold ownerHousehold = new OwnerHousehold();
        BeanUtils.copyProperties(dto, ownerHousehold);
        
        // 设置主业主标识
        ownerHousehold.setIsPrimaryOwner(dto.getIsPrimaryOwner() != null && dto.getIsPrimaryOwner() ? 1 : 0);
        ownerHousehold.setStatus(SystemStatusEnum.ENABLED.getCode());
        
        // 设置创建人和更新人
        Long currentUserId = SecurityUtils.getCurrentUserId();
        ownerHousehold.setCreateBy(currentUserId);
        ownerHousehold.setUpdateBy(currentUserId);
        LocalDateTime now = LocalDateTime.now();
        ownerHousehold.setCreateTime(now);
        ownerHousehold.setUpdateTime(now);
        
        // 保存关联信息
        this.save(ownerHousehold);
        
        log.info("创建业主房户关联成功，关联ID：{}", ownerHousehold.getId());
        return ownerHousehold.getId();
    }
    
    @Override
    @CacheEvict(value = {
        "owner_household:owner", "owner_household:household", "owner_household:vos", 
        "owner_household:household_vos", "owner_household:household_ids", "owner_household:owner_household", 
        "owner_household:primary", "owner_household:primary_households", "owner_household:exists", "owner_household:vo"
    }, allEntries = true)
    public void updateOwnerHousehold(Long id, OwnerHouseholdDTO dto) {
        log.info("更新业主房户关联，关联ID：{}", id);
        
        if (id == null) {
            throw new BusinessException("关联ID不能为空");
        }
        
        if (dto == null) {
            throw new BusinessException("关联信息不能为空");
        }
        
        // 检查关联是否存在
        OwnerHousehold existingRelation = this.getById(id);
        if (existingRelation == null) {
            throw new BusinessException("业主房户关联不存在");
        }
        
        // 更新关联信息 - 编辑时不修改ownerId和householdId
        log.info("更新前字段值 - mortgageInfo: {}, remark: {}", existingRelation.getMortgageInfo(), existingRelation.getRemark());
        log.info("DTO传入值 - mortgageInfo: {}, remark: {}", dto.getMortgageInfo(), dto.getRemark());
        
        existingRelation.setOwnershipType(dto.getOwnershipType());
        existingRelation.setOwnershipRatio(dto.getOwnershipRatio());
        existingRelation.setOwnershipStartDate(dto.getOwnershipStartDate());
        existingRelation.setOwnershipEndDate(dto.getOwnershipEndDate());
        existingRelation.setIsPrimaryOwner(dto.getIsPrimaryOwner() != null && dto.getIsPrimaryOwner() ? 1 : 0);
        existingRelation.setCertificateNumber(dto.getCertificateNumber());
        existingRelation.setCertificateDate(dto.getCertificateDate());
        existingRelation.setMortgageInfo(dto.getMortgageInfo());
        existingRelation.setRemark(dto.getRemark());
        
        log.info("更新后字段值 - mortgageInfo: {}, remark: {}", existingRelation.getMortgageInfo(), existingRelation.getRemark());
        

        
        // 设置更新人
        Long currentUserId = SecurityUtils.getCurrentUserId();
        existingRelation.setUpdateBy(currentUserId);
        existingRelation.setUpdateTime(LocalDateTime.now());
        
        // 更新关联信息
        log.info("准备更新数据库 - mortgageInfo: {}, remark: {}", existingRelation.getMortgageInfo(), existingRelation.getRemark());
        this.updateById(existingRelation);
        
        // 验证更新结果
        OwnerHousehold updatedRelation = this.getById(id);
        log.info("数据库更新后验证 - mortgageInfo: {}, remark: {}", updatedRelation.getMortgageInfo(), updatedRelation.getRemark());
        
        log.info("更新业主房户关联成功，关联ID：{}", id);
    }
    
    @Override
    @CacheEvict(value = {
        "owner_household:owner", "owner_household:household", "owner_household:vos", 
        "owner_household:household_vos", "owner_household:household_ids", "owner_household:owner_household", 
        "owner_household:primary", "owner_household:primary_households", "owner_household:exists", "owner_household:vo"
    }, allEntries = true)
    public void deleteOwnerHousehold(Long ownerId, Long householdId) {
        log.info("删除业主房户关联，业主ID：{}，房户ID：{}", ownerId, householdId);
        
        if (ownerId == null || householdId == null) {
            throw new BusinessException("业主ID和房户ID不能为空");
        }
        
        // 检查关联是否存在
        OwnerHousehold existingRelation = getByOwnerIdAndHouseholdId(ownerId, householdId);
        if (existingRelation == null) {
            throw new BusinessException("业主房户关联不存在");
        }
        
        // 删除关联信息
        this.removeById(existingRelation.getId());
        
        log.info("删除业主房户关联成功，关联ID：{}", existingRelation.getId());
    }
    
    @Override
    @CacheEvict(value = {
        "owner_household:owner", "owner_household:household", "owner_household:vos", 
        "owner_household:household_vos", "owner_household:household_ids", "owner_household:owner_household", 
        "owner_household:primary", "owner_household:primary_households", "owner_household:exists", "owner_household:vo"
    }, allEntries = true)
    public void deleteOwnerHousehold(Long id) {
        log.info("删除业主房户关联（根据关联ID），关联ID：{}", id);
        
        if (id == null) {
            throw new BusinessException("关联ID不能为空");
        }
        
        // 检查关联是否存在
        OwnerHousehold existingRelation = this.getById(id);
        if (existingRelation == null) {
            throw new BusinessException("业主房户关联不存在");
        }
        
        // 删除关联信息
        this.removeById(id);
        
        log.info("删除业主房户关联成功，关联ID：{}", id);
    }
    
    @Override
    @CacheEvict(value = {
        "owner_household:owner", "owner_household:household", "owner_household:vos", 
        "owner_household:household_vos", "owner_household:household_ids", "owner_household:owner_household", 
        "owner_household:primary", "owner_household:primary_households", "owner_household:exists", "owner_household:vo"
    }, allEntries = true)
    public void deleteByOwnerId(Long ownerId) {
        log.info("删除业主的所有房户关联，业主ID：{}", ownerId);
        
        if (ownerId == null) {
            return;
        }
        
        baseMapper.deleteByOwnerId(ownerId);
        
        log.info("删除业主的所有房户关联成功，业主ID：{}", ownerId);
    }
    
    @Override
    @CacheEvict(value = {
        "owner_household:owner", "owner_household:household", "owner_household:vos", 
        "owner_household:household_vos", "owner_household:household_ids", "owner_household:owner_household", 
        "owner_household:primary", "owner_household:primary_households", "owner_household:exists", "owner_household:vo"
    }, allEntries = true)
    public void deleteByHouseholdId(Long householdId) {
        log.info("删除房户的所有业主关联，房户ID：{}", householdId);
        
        if (householdId == null) {
            return;
        }
        
        baseMapper.deleteByHouseholdId(householdId);
        
        log.info("删除房户的所有业主关联成功，房户ID：{}", householdId);
    }
    
    @Override
    @CacheEvict(value = {
        "owner_household:owner", "owner_household:household", "owner_household:vos", 
        "owner_household:household_vos", "owner_household:household_ids", "owner_household:owner_household", 
        "owner_household:primary", "owner_household:primary_households", "owner_household:exists", "owner_household:vo"
    }, allEntries = true)
    public void setPrimaryOwner(Long ownerId, Long householdId) {
        log.info("设置主业主，业主ID：{}，房户ID：{}", ownerId, householdId);
        
        if (ownerId == null || householdId == null) {
            throw new BusinessException("业主ID和房户ID不能为空");
        }
        
        // 检查关联是否存在
        OwnerHousehold existingRelation = getByOwnerIdAndHouseholdId(ownerId, householdId);
        if (existingRelation == null) {
            throw new BusinessException("业主房户关联不存在");
        }
        
        // 先将该房户的所有业主设置为非主业主
        List<OwnerHousehold> allRelations = getByHouseholdId(householdId);
        for (OwnerHousehold relation : allRelations) {
            if (relation.getIsPrimaryOwner() == 1) {
                relation.setIsPrimaryOwner(0);
                this.updateById(relation);
            }
        }
        
        // 设置指定业主为主业主
        existingRelation.setIsPrimaryOwner(1);
        
        this.updateById(existingRelation);
        
        log.info("设置主业主成功，业主ID：{}，房户ID：{}", ownerId, householdId);
    }
    
    @Override
    @Cacheable(value = "owner_household:exists", key = "#ownerId + '_' + #householdId")
    public boolean existsByOwnerIdAndHouseholdId(Long ownerId, Long householdId) {
        if (ownerId == null || householdId == null) {
            return false;
        }
        
        OwnerHousehold relation = getByOwnerIdAndHouseholdId(ownerId, householdId);
        return relation != null;
    }
    
    @Override
    // 注意：移除@Cacheable注解，避免PageResult<OwnerHouseholdVO>复杂对象序列化/反序列化时的ClassCastException问题
    // 复杂对象（如PageResult、IPage、自定义VO等）在Redis缓存中容易出现类型转换错误
    // 遵循《Java后端SpringBoot代码开发规范.md》的缓存使用规范
    public PageResult<OwnerHouseholdVO> getOwnerHouseholdPage(OwnerHouseholdQueryDTO queryDTO) {
        log.info("分页查询业主房户关联列表，查询条件：{}", queryDTO);
        
        if (queryDTO == null) {
            return PageResult.of(1, 10, 0L, Collections.emptyList());
        }
        
        // 构建查询条件
        LambdaQueryWrapper<OwnerHousehold> queryWrapper = new LambdaQueryWrapper<>();
        
        // 业主ID条件
        if (queryDTO.getOwnerId() != null) {
            queryWrapper.eq(OwnerHousehold::getOwnerId, queryDTO.getOwnerId());
        }
        
        // 房户ID条件
        if (queryDTO.getHouseholdId() != null) {
            queryWrapper.eq(OwnerHousehold::getHouseholdId, queryDTO.getHouseholdId());
        }
        
        // 产权类型条件
        if (queryDTO.getOwnershipType() != null) {
            queryWrapper.eq(OwnerHousehold::getOwnershipType, queryDTO.getOwnershipType());
        }
        
        // 主业主条件
        if (queryDTO.getIsPrimaryOwner() != null) {
            queryWrapper.eq(OwnerHousehold::getIsPrimaryOwner, queryDTO.getIsPrimaryOwner() ? 1 : 0);
        }
        
        // 状态条件
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq(OwnerHousehold::getStatus, queryDTO.getStatus());
        }
        
        // 关键词搜索
        if (StringUtils.hasText(queryDTO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper
                .like(OwnerHousehold::getCertificateNumber, queryDTO.getKeyword())
                .or()
                .like(OwnerHousehold::getRemark, queryDTO.getKeyword())
            );
        }
        
        // 时间范围条件
        if (StringUtils.hasText(queryDTO.getStartTime())) {
            queryWrapper.ge(OwnerHousehold::getCreateTime, queryDTO.getStartTime());
        }
        if (StringUtils.hasText(queryDTO.getEndTime())) {
            queryWrapper.le(OwnerHousehold::getCreateTime, queryDTO.getEndTime());
        }
        
        // 排序
        queryWrapper.orderByDesc(OwnerHousehold::getCreateTime);
        
        // 分页查询
        Page<OwnerHousehold> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        IPage<OwnerHousehold> result = this.page(page, queryWrapper);
        
        // 转换为VO
        List<OwnerHouseholdVO> voList = convertToVOList(result.getRecords());
        
        log.info("分页查询业主房户关联列表成功，总记录数：{}", result.getTotal());
        return PageResult.of(queryDTO.getCurrent(), queryDTO.getSize(), result.getTotal(), voList);
    }
    
    @Override
    @Cacheable(value = "owner_household:vo", key = "#id", unless = "#result == null")
    public OwnerHouseholdVO getOwnerHouseholdVOById(Long id) {
        log.info("根据ID获取业主房户关联详情，关联ID：{}", id);
        
        if (id == null) {
            throw new BusinessException("关联ID不能为空");
        }
        
        OwnerHousehold ownerHousehold = this.getById(id);
        if (ownerHousehold == null) {
            throw new BusinessException("业主房户关联不存在");
        }
        
        OwnerHouseholdVO vo = convertToVO(ownerHousehold);
        
        log.info("获取业主房户关联详情成功，关联ID：{}", id);
        return vo;
    }
    
    /**
     * 将实体对象转换为VO对象
     * 
     * @param ownerHousehold 实体对象
     * @return VO对象
     */
    private OwnerHouseholdVO convertToVO(OwnerHousehold ownerHousehold) {
        if (ownerHousehold == null) {
            return null;
        }
        
        OwnerHouseholdVO vo = new OwnerHouseholdVO();
        BeanUtils.copyProperties(ownerHousehold, vo);
        
        // 设置主业主标识
        vo.setIsPrimaryOwner(ownerHousehold.getIsPrimaryOwner() == 1);
        
        // 设置状态描述
        vo.setStatusDesc(ownerHousehold.getStatus() == 1 ? "启用" : "禁用");
        
        // 设置产权类型描述
        switch (ownerHousehold.getOwnershipType()) {
            case 1:
                vo.setOwnershipTypeDesc("完全产权");
                break;
            case 2:
                vo.setOwnershipTypeDesc("共有产权");
                break;
            case 3:
                vo.setOwnershipTypeDesc("部分产权");
                break;
            default:
                vo.setOwnershipTypeDesc("未知");
        }
        
        // 获取业主详细信息
        try {
            Owner owner = ownerMapper.selectById(ownerHousehold.getOwnerId());
            if (owner != null) {
                vo.setOwnerName(owner.getOwnerName());
                vo.setOwnerIdCard(owner.getIdCard());
                vo.setOwnerPhone(owner.getPhone());
            } else {
                vo.setOwnerName("业主" + ownerHousehold.getOwnerId());
                vo.setOwnerIdCard("身份证号待查询");
                vo.setOwnerPhone("电话待查询");
            }
        } catch (Exception e) {
            log.warn("获取业主信息失败，业主ID：{}", ownerHousehold.getOwnerId(), e);
            vo.setOwnerName("业主" + ownerHousehold.getOwnerId());
            vo.setOwnerIdCard("身份证号待查询");
            vo.setOwnerPhone("电话待查询");
        }
        
        // 获取房户详细信息
        try {
            Household household = householdService.getById(ownerHousehold.getHouseholdId());
            if (household != null) {
                vo.setRoomNumber(household.getRoomNumber());
                
                // 获取单元信息
                Unit unit = unitService.getById(household.getUnitId());
                if (unit != null) {
                    vo.setUnitName(unit.getUnitName());
                    
                    // 获取楼栋信息
                    Building building = buildingService.getById(unit.getBuildingId());
                    if (building != null) {
                        vo.setBuildingName(building.getBuildingName());
                        
                        // 获取小区信息
                        Community community = communityService.getById(building.getCommunityId());
                        if (community != null) {
                            vo.setCommunityName(community.getCommunityName());
                        } else {
                            vo.setCommunityName("小区待查询");
                        }
                    } else {
                        vo.setBuildingName("楼栋待查询");
                        vo.setCommunityName("小区待查询");
                    }
                } else {
                    vo.setUnitName("单元待查询");
                    vo.setBuildingName("楼栋待查询");
                    vo.setCommunityName("小区待查询");
                }
            } else {
                vo.setRoomNumber("房间号待查询");
                vo.setUnitName("单元待查询");
                vo.setBuildingName("楼栋待查询");
                vo.setCommunityName("小区待查询");
            }
        } catch (Exception e) {
            log.warn("获取房户信息失败，房户ID：{}", ownerHousehold.getHouseholdId(), e);
            vo.setRoomNumber("房间号待查询");
            vo.setUnitName("单元待查询");
            vo.setBuildingName("楼栋待查询");
            vo.setCommunityName("小区待查询");
        }
        
        return vo;
    }
    
    /**
     * 将实体对象列表转换为VO对象列表
     * 
     * @param ownerHouseholds 实体对象列表
     * @return VO对象列表
     */
    private List<OwnerHouseholdVO> convertToVOList(List<OwnerHousehold> ownerHouseholds) {
        if (ownerHouseholds == null || ownerHouseholds.isEmpty()) {
            return Collections.emptyList();
        }
        
        return ownerHouseholds.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }
    
    @Override
    public void clearCacheByOwnerId(Long ownerId) {
        if (ownerId == null) {
            return;
        }
        
        try {
            // 清除业主相关的缓存
            cacheManager.getCache("owner_household:owner").evict(ownerId);
            log.info("清除业主缓存成功，业主ID：{}", ownerId);
        } catch (Exception e) {
            log.warn("清除业主缓存失败，业主ID：{}，错误：{}", ownerId, e.getMessage());
        }
    }
}
